import pandas  as pd



'''
NumPy（Numerical Python）是 Python 中用于科学计算的一个开源库，它提供了多维数组对象（例如数组）、用于数组操作的函数以及线性代数等工具。以下是 NumPy 的一些重要特性和用途：

多维数组（Arrays）：NumPy 提供了一个名为 ndarray 的多维数组对象，它是具有相同数据类型（通常是数值类型）的元素的多维容器。这使得 NumPy 可以高效地存储和操作大型数据集。

广播（Broadcasting）：NumPy 支持广播操作，允许在不同形状的数组之间执行算术运算，而无需显式循环。

矢量化操作：NumPy 支持矢量化操作，允许对整个数组执行算术和其他操作，而无需编写显式循环。

线性代数操作：NumPy 提供了用于线性代数运算的函数，包括矩阵乘法、求逆、特征值分解等。

随机数生成器：NumPy 包含一个随机数模块，用于生成各种随机数分布的样本。

整合其他语言：NumPy 是基于 C 语言编写的，因此在性能方面表现出色，并且可以轻松与其他基于 C 或 Fortran 的库集成。

科学计算：NumPy 广泛应用于科学计算、数据分析、机器学习、图像处理等领域。
'''
import numpy as np
# 查看版本
print(pd.__version__)




mydataset = {
    'name': ["张国荣", "张学友", "刘德华"],
    'age': [40, 53, 45],
    'gender': ['男','男','男']
}
# 将列表转化为DF
myvar = pd.DataFrame(mydataset)

print(myvar)




print('-----------------------------------------------分割线---------------------------------------------------')

print("-------------下面研究Series-------------")
'''
Pandas Series 类似表格中的一个列（column），类似于一维数组，可以保存任何数据类型。

Series 的数据结构是非常有用的，因为它可以处理各种数据类型，同时保持了高效的数据操作能力。

Series 特点：
        
        一维数组： Series是一维的，这意味着它只有一个轴（或维度），类似于 Python 中的列表。
        索   引： 每个 Series 都有一个索引，它可以是整数、字符串、日期等类型。如果不指定索引，Pandas 将默认创建一个从 0 开始的整数索引。
        数据类型： Series 可以容纳不同数据类型的元素，包括整数、浮点数、字符串、Python 对象等。 
        大小不变性：Series 的大小在创建后是不变的，但可以通过某些操作（如 append 或 delete）来改变。   
        操   作： Series 支持各种操作，如数学运算、统计分析、字符串处理等。
        缺失数据： Series 可以包含缺失数据，Pandas 使用NaN（Not a Number）来表示缺失或无值。
        
        
创建Series
        可以使用 pd.Series() 构造函数创建一个 Series 对象，传递一个数据数组（可以是列表、NumPy 数组等）和一个可选的索引数组。
        
        pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False) 

参数说明：
    data：Series 的数据部分，可以是列表、数组、字典、标量值等。如果不提供此参数，则创建一个空的 Series。
    index：Series 的索引部分，用于对数据进行标记。可以是列表、数组、索引对象等。如果不提供此参数，则创建一个默认的整数索引。
    dtype：指定 Series 的数据类型。可以是 NumPy 的数据类型，例如 np.int64、np.float64 等。如果不提供此参数，则根据数据自动推断数据类型。
    name：Series 的名称，用于标识 Series 对象。如果提供了此参数，则创建的 Series 对象将具有指定的名称。
    copy：是否复制数据。默认为 False，表示不复制数据。如果设置为 True，则复制输入的数据。
    fastpath：是否启用快速路径。默认为 False。启用快速路径可能会在某些情况下提高性能。
        
        
'''





# 演示
# 数据
a = [1, 2, 3]
# 指定索引
b = ['a','b','c']

print( pd.Series(a,b,float,))



print('------------------------------------测试一下copy--------------------------------')

data = [1, 2, 3, 4, 5]
index = ['A', 'B', 'C', 'D', 'E']
print(f'修改之前的原始数据 {data}')
# 创建 Series 对象，并指定 copy=True
series_copy_true = pd.Series(data=data, index=index,name='series的名字', copy=False)

# 修改原始数据
data[0] = 100
print(f'修改之后的原始数据 {data}')
# 打印 Series 对象
print(series_copy_true['D'])





sites = {1: "Google", 2: "Runoob", 3: "Wiki"}



print(f'使用key/velues对象创建Series：{pd.Series(sites)}')

print('------------------------------------使用列表、字典或数组创建一个默认索引的 Series--------------------------------')
# 使用列表创建 Series
s1 = pd.Series([1, 2, 3, 4])

# 使用 NumPy 数组创建 Series
s2 = pd.Series(np.array([1, 2, 3, 4]))

# 使用字典创建 Series
s3 = pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4})

# 打印三个 Series 对象
print(f"使用列表创建 Series:{ pd.Series([1, 2, 3, 4])}")

print(f"使用 NumPy 数组创建 Series:{ pd.Series(np.array([1, 2, 3, 4]))}")

print(f"使用字典创建 Series:{pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4})}")
print(s3)



print('------------------------------------基本操作--------------------------------')

# 指定索引创建 Series
s = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])

data = [10, 20, 30, 40, 50]
series =  pd.Series(data)

# 获取值
value = series[2]  # 获取索引为2的值
print(value)
print(s['a'])  # 返回索引标签 'a' 对应的元素

# 获取多个值
print(series[1:4])  # 获取索引为1到3的值

# 索引和值的对应关系
for index, value in series.items():
    print(f"Index: {index}, Value: {value}")

# 使用切片语法来访问 Series 的一部分
print(s['a':'c'])  # 返回索引标签 'a' 到 'c' 之间的元素
print(s[:3])  # 返回前三个元素



print(f'没有删除之前的：{s}')
# 为特定的索引标签赋值
s['a'] = 10  # 将索引标签 'a' 对应的元素修改为 10
print(f'修改值：{s}')
# 通过赋值给新的索引标签来添加元素
s['e'] = 5  # 在 Series 中添加一个新的元素，索引标签为 'e'
print(f'添加值：{s}')
# 使用 del 删除指定索引标签的元素。
del s['a']  # 删除索引标签 'a' 对应的元素
print(f'del 方法删除指定索引值之后的：{s}')
# 使用 drop 方法删除一个或多个索引标签，并返回一个新的 Series。
s_dropped = s.drop(['b'])  # 返回一个删除了索引标签 'b' 的新 Series
print(f'drop 方法删除指定索引值之后的：{s}')




print('------------------------------------基本运算--------------------------------')

# 算术运算
result = series * 2  # 所有元素乘以2
print(result)
# 过滤
filtered_series = series[series > 2]  # 选择大于2的元素
print(filtered_series)
# 数学函数

result = np.sqrt(series)  # 对每个元素取平方根
print(result)




# 计算统计数据：使用 Series 的方法来计算描述性统计。

print(s.sum())  # 输出 Series 的总和
print(s.mean())  # 输出 Series 的平均值
print(s.max())  # 输出 Series 的最大值
print(s.min())  # 输出 Series 的最小值
print(s.std())  # 输出 Series 的标准差




# 属性和方法：
print('------------------------------------属性和方法--------------------------------')

# s = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
# 获取索引
print(f'获取索引:{s.index}')

# 获取值数组
print(f'获取值数组:{s.values}')

# 获取描述统计信息
'''
获取描述统计信息：s.describe() 是 Pandas Series 对象的一个方法，用于计算该 Series 的描述统计信息，包括计数、均值、标准差、最小值、25%、50%、75% 四分位数以及最大值。
计数（count）：非缺失值的数量。
均值（mean）：所有值的平均值。
标准差（std）：所有值的标准差。
最小值（min）：所有值中的最小值。
25%、50%、75% 四分位数：分别表示数据中值的 25%、50%（中位数）、75% 的位置。
最大值（max）：所有值中的最大值。
'''
print(f'获取描述统计信息:{s.describe()}')

# 获取最大值和最小值的索引
print(f'获取最大值的索引: {s.idxmax()}')
print(f'最小值的索引{s.idxmin()}')

# 其他属性和方法
print(f'数据类型: {s.dtype}')   # 数据类型
print(f'形状: {s.shape}')   # 形状
print(f'元素个数: {s.size}')    # 元素个数
print(f'前几个元素，默认是前 5 个: {s.head()}')  # 前几个元素，默认是前 5 个
print(f'后几个元素，默认是后 5 个: {s.tail()}')  # 后几个元素，默认是后 5 个
print(f'求和: {s.sum()}')   # 求和
print(f'平均值: {s.mean()}')  # 平均值
print(f'标准差: {s.std()}')   # 标准差
print(f'最小值: {s.min()}')   # 最小值
print(f'最大值: {s.max()}')   # 最大值



print('------------------------------------分割线--------------------------------')
# 使用布尔表达式：根据条件过滤 Series。

print(s > 2)  # 返回一个布尔 Series，其中的元素值大于 2
# 查看数据类型：使用 dtype 属性查看 Series 的数据类型。

print(s.dtype)  # 输出 Series 的数据类型
# 转换数据类型：使用 astype 方法将 Series 转换为另一种数据类型。

s = s.astype('float64')  # 将 Series 中的所有元素转换为 float64 类型